import { _decorator, Component, Node, Button, Label, Color, director, find, JsonAsset, Sprite, tween, v3, UIOpacity, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

import { SSS_Consts } from "../../../../Script/Data/SSS_Consts";
import { bdlMgr } from "../../../../Script/Manager/BundleManager_S";
import { Suan24Dian_GameData } from "../Suan24Dian_GameData";
import Suan24Dian_GameManager from "../Suan24Dian_GameManager";
import { Suan24Dian_GameStorage } from "../Suan24Dian_GameStorage";
import { SSS_AudioManager } from 'db://assets/Script/Manager/SSS_AudioManager';
// // 分数类定义
class Fraction {
    constructor(
        public numerator: number,
        public denominator: number = 1
    ) {
        this.simplify();
    }
    //     // 计算最大公约数
    private gcd(a: number, b: number): number {
        return b === 0 ? a : this.gcd(b, a % b);
    }
    //     // 约分
    private simplify(): void {
        if (this.numerator === 0) {
            this.denominator = 1;
            return;
        }
        const divisor = this.gcd(Math.abs(this.numerator), Math.abs(this.denominator));
        this.numerator /= divisor;
        this.denominator /= divisor;
        //         // 确保分母为正
        if (this.denominator < 0) {
            this.numerator = -this.numerator;
            this.denominator = -this.denominator;
        }
    }
    //     // 加法
    add(other: Fraction): Fraction {
        const newNumerator = this.numerator * other.denominator + other.numerator * this.denominator;
        const newDenominator = this.denominator * other.denominator;
        return new Fraction(newNumerator, newDenominator);
    }
    //     // 减法
    subtract(other: Fraction): Fraction {
        const newNumerator = this.numerator * other.denominator - other.numerator * this.denominator;
        const newDenominator = this.denominator * other.denominator;
        return new Fraction(newNumerator, newDenominator);
    }
    //     // 乘法
    multiply(other: Fraction): Fraction {
        const newNumerator = this.numerator * other.numerator;
        const newDenominator = this.denominator * other.denominator;
        return new Fraction(newNumerator, newDenominator);
    }
    //     // 除法
    divide(other: Fraction): Fraction {
        const newNumerator = this.numerator * other.denominator;
        const newDenominator = this.denominator * other.numerator;
        return new Fraction(newNumerator, newDenominator);
    }
    //     // 转换为字符串
    toString(): string {
        if (this.denominator === 1) {
            return this.numerator.toString();
        }
        return `${this.numerator}/${this.denominator}`;
    }
    //     // 转换为数值
    toNumber(): number {
        return this.numerator / this.denominator;
    }
    //     // 判断是否等于24
    is24(): boolean {
        return Math.abs(this.toNumber() - 24) < 1e-6;
    }
}

// CocosCreator3.8.4
@ccclass('Suan24DianGamePanel')
export default class Suan24Dian_GamePanel extends Component {
    @property(Node)
    Button_back: Node | null = null;
    @property([Button])
    numberButtons: Button[] = [];
    @property([Label])
    numberLabels: Label[] = [];
    @property(Label)
    labelResult: Label | null = null;
    @property(Button)
    Button_submit: Button | null = null;
    @property(Button)
    Button_refresh: Button | null = null;
    @property(Button)
    Button_add: Button | null = null;
    @property(Button)
    Button_sub: Button | null = null;
    @property(Button)
    Button_mul: Button | null = null;
    @property(Button)
    Button_div: Button | null = null;
    @property(Label)
    Label_level: Label | null = null;
    //    // 下一关按钮
    @property(Node)
    Button_next: Node | null = null;
    @property(Node)
    ad: Node | null = null;
    @property(Label)
    Label_tip_number: Label | null = null;
    @property(Node)
    Button_tip: Node | null = null;
    private numbers: number[] = [];
    private firstIndex: number = -1;
    private operator: string = '';
    private isAnimating: boolean = false;
    private operatorButtons: { [key: string]: Button } = {};
    color_紫色 = `#552583`;
    color_金色 = `#FDB927`;
    color_select = `#528BCF`;
    color_OperatorSelected = `#528BCF`;
    color_canel = `#7B7BCB`;
    Refresh_tip() {
        this.Label_tip_number.string = `${Suan24Dian_GameStorage.data.tip_number}`;
        this.ad.active = Suan24Dian_GameStorage.data.tip_number <= 0;
    }
    On_Button_tip() {
        console.log(`提示`)

        if (Suan24Dian_GameStorage.data.tip_number > 0) {
            Suan24Dian_GameStorage.data.tip_number--;
            Suan24Dian_GameStorage.saveData();
            this.Refresh_tip();

            this.提示回调();
        }
        else {
            Suan24Dian_GameStorage.data.tip_number += Suan24Dian_GameData.add_tip_number;
            Suan24Dian_GameStorage.saveData();
            this.Refresh_tip();
        }
    }
    提示回调() {
        this.labelResult.node.active = true;
        // 获取当前数字的所有解法
        const solutions = Suan24Dian_GameManager.getAllSolutions(this.numbers);
        if (solutions && solutions.length > 0) {
            // 显示第一个解法作为提示
            this.labelResult.string = `提示: ${solutions[0]}`;
        } else {
            this.labelResult.string = "当前无解，尝试刷新数字!";
        }

        // // 3秒后隐藏提示
        // this.scheduleOnce(() => {
        //     this.labelResult.node.active = false;
        // }, 3);
    }
    async onLoad() {
        Suan24Dian_GameStorage.initData();

        this.Refresh_tip();

        this.Button_tip.on(Node.EventType.TOUCH_START, this.On_Button_tip, this);

        let level_json = await bdlMgr.getRes<JsonAsset>(`Suan24Dian_level_data`, `24_game_with_better_levels`, JsonAsset)

        console.log(`level_json`, level_json)
        console.log(`level_json.json`, level_json.json)

        if (level_json) {
            Suan24Dian_GameData.level_data_list = level_json.json;
        }



        this.Button_next.on(Node.EventType.TOUCH_END, this.下一关, this);

        this.Button_refresh.node.on(Node.EventType.TOUCH_END, this.On_Button_refresh, this);
        this.Button_back.on(Node.EventType.TOUCH_END, this.On_Button_back, this);
        this.Button_add.node.on(Node.EventType.TOUCH_END, () => this.onOperatorClick('+'), this);
        this.Button_sub.node.on(Node.EventType.TOUCH_END, () => this.onOperatorClick('-'), this);
        this.Button_mul.node.on(Node.EventType.TOUCH_END, () => this.onOperatorClick('*'), this);
        this.Button_div.node.on(Node.EventType.TOUCH_END, () => this.onOperatorClick('/'), this);

        // 计算
        for (let i = 0; i < this.numberButtons.length; i++) {
            this.numberButtons[i].node.on(Node.EventType.TOUCH_END, () => this.onNumberClick(i), this);
        }

        this.operatorButtons = {
            '+': this.Button_add,
            '-': this.Button_sub,
            '*': this.Button_mul,
            '/': this.Button_div
        };
        this.refreshNumbers();

        this.Refresh_level();
    }
    Refresh_level() {
        this.Label_level.string = `第${Suan24Dian_GameData.Get_CurrentLevelIndex()}关`
        console.log(`Suan24Dian_GameData.Get_CurrentLevelIndex()`, Suan24Dian_GameData.Get_CurrentLevelIndex())
    }
    On_Button_back() {
        director.loadScene(SSS_Consts.SceneName.MainScene);
        SSS_AudioManager.PlayButtonAudio();
    }
    refreshNumbers() {
        this.numbers = Suan24Dian_GameData.Get_numbers();
        console.log(`this.numbers`, this.numbers);

        for (let i = 0; i < 4; i++) {
            if (this.numberLabels[i]) {
                this.numberLabels[i].string = this.numbers[i].toString();
                this.numberButtons[i].interactable = true;

                // 改成CocosCreator3.8.4 api
                this.numberButtons[i].node.getComponent(UIOpacity).opacity = 255;
                this.highlightButton(i, false);
                this.numberButtons[i].node.setPosition(this.numberButtons[i]['_originPos'] || this.numberButtons[i].node.position);
                this.setButtonSelected(this.numberButtons[i], false);
            }
        }
        this.labelResult.string = "";
        this.firstIndex = -1;
        this.operator = '';
        this.isAnimating = false;
        this.setAllOperatorSelected(false);
    }
    下一关() {
        Suan24Dian_GameStorage.data.current_level++;
        Suan24Dian_GameStorage.saveData();
        this.Refresh_level();
        this.refreshNumbers();

        director.loadScene(SSS_Consts.SceneName.Suan24Dian_Game_Scene);
    }
    onNumberClick(idx: number) {
        if (this.isAnimating || !this.numberButtons[idx].interactable) return;
        if (this.firstIndex === idx) {
            // 再次点击已选中的数字，取消选中
            this.firstIndex = -1;
            this.highlightButton(idx, false);
            this.setButtonSelected(this.numberButtons[idx], false);
            // 不再清空运算符
            return;
        }
        if (this.firstIndex === -1) {
            // 选第一个数
            this.firstIndex = idx;
            this.highlightButton(idx, true);
            this.setButtonSelected(this.numberButtons[idx], true);
            // 不再清空运算符
        } else if (!this.operator) {
            // 已选中一个数字，再点别的数字，切换选中
            this.highlightButton(this.firstIndex, false);
            this.setButtonSelected(this.numberButtons[this.firstIndex], false);
            this.firstIndex = idx;
            this.highlightButton(idx, true);
            this.setButtonSelected(this.numberButtons[idx], true);
            // 不再清空运算符
        } else if (this.operator && idx !== this.firstIndex) {
            // 选第二个数并执行
            this.doOperation(this.firstIndex, idx, this.operator);
        }
    }
    onOperatorClick(op: string) {
        if (this.operator === op) {
            // 再次点击已选中的运算符，取消选中
            this.setOperatorSelected(op, false);
            this.operator = '';
            return;
        }
        this.operator = op;
        this.setAllOperatorSelected(false);
        this.setOperatorSelected(op, true);
    }
    //    // 获取数字的分数表示
    private getNumberAsFraction(index: number): Fraction {
        const value = this.numbers[index];

        // 检查当前显示的是否已经是分数形式
        const currentDisplay = this.numberLabels[index].string;
        if (currentDisplay.includes('/')) {
            const [numerator, denominator] = currentDisplay.split('/').map(Number);
            return new Fraction(numerator, denominator);
        }

        // 如果是整数，直接返回
        if (Number.isInteger(value)) {
            return new Fraction(value);
        }

        // 尝试将小数转换为分数
        const tolerance = 1e-6;
        for (let denom = 1; denom <= 100; denom++) {
            const numerator = Math.round(value * denom);
            if (Math.abs(value - numerator / denom) < tolerance) {
                return new Fraction(numerator, denom);
            }
        }

        // 如果无法精确表示为分数，使用近似值
        return new Fraction(Math.round(value * 1000000), 1000000);
    }
    doOperation(first: number, second: number, op: string) {
        if (this.isAnimating) return;
        this.isAnimating = true;

        // 使用Fraction来处理所有运算
        const a = this.getNumberAsFraction(first);
        const b = this.getNumberAsFraction(second);
        let result: Fraction;

        switch (op) {
            case '+':
                result = a.add(b);
                break;
            case '-':
                result = a.subtract(b);
                break;
            case '*':
                result = a.multiply(b);
                break;
            case '/':
                if (b.numerator === 0) {
                    this.labelResult.string = "不能除以0!";
                    this.isAnimating = false;
                    return;
                }
                result = a.divide(b);
                break;
            default:
                this.isAnimating = false;
                return;
        }

        // 存储数值（内部仍然使用数值存储）
        this.numbers[second] = result.toNumber();

        // 显示分数形式（避免小数）
        this.numberLabels[second].string = result.toString();

        // 动画：first按钮移动到second按钮位置
        const firstNode = this.numberButtons[first].node;
        const secondNode = this.numberButtons[second].node;
        if (!this.numberButtons[first]['_originPos']) this.numberButtons[first]['_originPos'] = firstNode.position.clone();
        if (!this.numberButtons[second]['_originPos']) this.numberButtons[second]['_originPos'] = secondNode.position.clone();

        tween(firstNode)
            .to(0.3, { position: secondNode.position })
            .call(() => {
                // 合并完成
                this.numberButtons[first].interactable = false;
                this.numberButtons[first].node.getComponent(UIOpacity).opacity = 100;
                this.numberButtons[first].node.active = false;

                this.highlightButton(first, false);
                this.setButtonSelected(this.numberButtons[first], false);

                // 选中合并后的数字
                this.firstIndex = second;
                this.highlightButton(second, true);
                this.setButtonSelected(this.numberButtons[second], true);

                // 清空运算符
                this.operator = '';
                this.setAllOperatorSelected(false);

                this.isAnimating = false;

                //    改成 3.8.4tween
                // 检查是否只剩一个数且为24
                if (this.getActiveCount() === 1 && result.is24()) {
                    this.labelResult.string = "恭喜你，算出24点！";
                    // 胜利动画
                    const btnNode = this.numberButtons[second].node;
                    const centerPos = v3(0, 0, 0);
                    tween(btnNode)
                        .to(0.5, { position: centerPos, scale: new Vec3(2, 2, 2) })
                        .start();

                    let bg = find(`bg`, btnNode).getComponent(Sprite);
                    tween(bg)
                        .to(0.5, { color: Color.fromHEX(new Color(), this.color_紫色) })
                        .start();

                    let Label1 = find(`Label`, btnNode).getComponent(Label);
                    tween(Label1)
                        .to(0.5, { color: Color.fromHEX(new Color(), this.color_金色) })
                        .start();

                    this.Button_next.active = true;
                }
            })
            .start();
    }
    highlightButton(idx: number, highlight: boolean) {
        //        // 保持原有样式
    }
    setButtonSelected(btn: Button, selected: boolean) {
        // btn.node.color = selected ? new Color().fromHEX(this.color_select) : new Color().fromHEX(this.color_canel);
        let sprite = btn.node.getComponentInChildren(Sprite);
        if (sprite) {
            sprite.color = selected ? new Color().fromHEX(this.color_select) : new Color().fromHEX(this.color_canel);
        }
    }
    setOperatorSelected(op: string, selected: boolean) {
        const btn = this.operatorButtons[op];
        if (btn) {
            // btn.node.color = selected ? new Color().fromHEX(this.color_OperatorSelected) : new Color().fromHEX(this.color_canel);
            let sprite = btn.node.getComponentInChildren(Sprite);
            if (sprite) {
                sprite.color = selected ? new Color().fromHEX(this.color_OperatorSelected) : new Color().fromHEX(this.color_canel);
            }
        }
    }
    setAllOperatorSelected(selected: boolean) {
        for (const op in this.operatorButtons) {
            this.setOperatorSelected(op, selected && this.operator === op);
        }
    }
    getActiveCount(): number {
        return this.numberButtons.filter(btn => btn.interactable).length;
    }
    On_Button_refresh() {
        this.Replay();
        SSS_AudioManager.PlayButtonAudio();
    }
    Replay() {
        Suan24Dian_GameData.ClearData();
        let currentSceneName = director.getScene().name;
        director.loadScene(currentSceneName);
    }
}

